﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace HardStyle.SimpleEventBus.Internal
{
    internal abstract class SimpleEventHandlerWrapper
    {
        public abstract Task Handle(ISimpleEvent e, CancellationToken cancellationToken, ServiceFactory serviceFactory,
            Func<IEnumerable<Func<ISimpleEvent, CancellationToken, Task>>, ISimpleEvent, CancellationToken, Task> publish);
    }

    internal class SimpleEventHandlerWrapperImp<TEvent> : SimpleEventHandlerWrapper
        where TEvent : ISimpleEvent
    {
        public override Task Handle(ISimpleEvent e, CancellationToken cancellationToken, ServiceFactory serviceFactory, Func<IEnumerable<Func<ISimpleEvent, CancellationToken, Task>>, ISimpleEvent, CancellationToken, Task> publish)
        {
            var handlers = serviceFactory.GetInstances<ISimpleEventHandle<TEvent>>()
                 .Select(x => new Func<ISimpleEvent, CancellationToken, Task>((theEvent, theToken) => x.Handle((TEvent)theEvent, theToken)));

            return publish(handlers, e, cancellationToken);
        }
    }
}
